#pragma once
#include <vector>
#include "bspline_curve.h"

using std::vector;

namespace shermit {
	//////////////////////////////////////////////////////////////////////
	//
	// CubicBSplineCurve on CPU
	//
	//////////////////////////////////////////////////////////////////////
	template<typename Float_t>
	class BSplineCurve<Float_t, 3, DeviceType::CPU> {
	public:
		using vec_t = nv::vec2<Float_t>;
		BSplineCurve<Float_t, 3, DeviceType::CPU>();

		int degree() const;  // max degree of the curve's polynomials
		int nControlPts() const;  // num of control points
		int nKnots() const;  // num of knots
		const vec_t* getControlPts() const; // get control points array
		Float_t tMin() const;  // parameter t in range [tMin, tMax)
		Float_t tMax() const;

		vec_t at(Float_t t) const;
		vec_t df(Float_t t, unsigned int order) const; // k-order differential of f(t)
		vec_t tangent(Float_t t) const;
		vec_t normal(Float_t t) const;  // pointing away from the curvature circle
		Float_t curvature(Float_t t) const;

		void addControlPt(const vec_t& pt);
		void setControlPt(int i, vec_t& pt);
		void setControlPts(const vec_t* pts, int num_pts, DeviceType from);
		void deallocate();

		void copyToDevice(BSplineCurve<Float_t, 3, DeviceType::GPU>& d_curve) const;

	private:
		vec_t df1(Float_t t) const;
		vec_t df2(Float_t t) const;
	protected:
		vector<vec_t> control_pts;
	};
}